package com.wecan.micro.exception;

import cn.dev33.satoken.exception.NotLoginException;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.wecan.base.exception.AppException;
import com.wecan.base.exception.AppExceptionHandler;
import com.wecan.base.exception.app.UnauthorizedClientException;
import com.wecan.base.model.Result;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @Author liuzhihao
 * @Date 2022.01.12
 * @Version ${version}
 * @Description ${description}
 */
public class GlobalWebExceptionHandler {
    @ExceptionHandler({Exception.class, AppException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<String> exception(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        Result<String> result = resolveException(ex, request.getRequestURI());
        return result;
    }

    @ExceptionHandler({NotLoginException.class, UnauthorizedClientException.class})
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Result<String> notLoginException(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        Result<String> result = resolveException(ex, request.getRequestURI());
        return result;
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Result<String> noHandlerFoundException(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        Result<String> result = resolveException(ex, request.getRequestURI());
        response.setStatus(result.getStatus());
        return result;
    }


    @ExceptionHandler({HttpClientErrorException.class, HttpServerErrorException.class})
    public Result<String> restTemplateException(Exception ex, HttpServletRequest request, HttpServletResponse response) {
        Result<String> result = resolveException(ex, request.getRequestURI());
        response.setStatus(result.getStatus());
        return result;
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result<String> validationMethodArgumentException(MethodArgumentNotValidException ex, HttpServletRequest request, HttpServletResponse response) {
        return validationBindException(ex, request, response);
    }

    @ExceptionHandler({BindException.class})
    public Result<String> validationBindException(BindException ex, HttpServletRequest request, HttpServletResponse response) {
        Result<String> result = resolveException(ex, request.getRequestURI());

        BindingResult bindingResult = ex.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        //返回第一个错误的信息
        if (ObjectUtils.isNotEmpty(fieldError)) {
            result.validation(fieldError.getDefaultMessage(), fieldError.getCode(), fieldError.getField());
        }

        response.setStatus(result.getStatus());
        return result;
    }

    public Result<String> resolveException(Exception ex, String path) {
        return AppExceptionHandler.resolveException(ex, path);
    }
}
